package com.wenx.v3system.modular.cloud.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wenx.v3core.error.BusinessException;
import com.wenx.v3system.modular.cloud.domain.po.SysPermission;
import com.wenx.v3system.modular.cloud.domain.po.SysRolePermission;
import com.wenx.v3system.modular.cloud.mapper.SysPermissionMapper;
import com.wenx.v3system.modular.cloud.mapper.SysRolePermissionMapper;
import com.wenx.v3system.modular.cloud.service.SysRolePermissionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统角色权限关联服务实现类
 * 管理角色与权限的多对多关系
 *
 * @author wenx
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysRolePermissionServiceImpl extends ServiceImpl<SysRolePermissionMapper, SysRolePermission> implements SysRolePermissionService {

    // 缓存常量
    private static final String ROLE_PERMISSIONS_CACHE = "sys:role:permissions";
    private static final String PERMISSION_ROLES_CACHE = "sys:permission:roles";

    private final SysPermissionMapper permissionMapper;

    @Override
    @Cacheable(value = ROLE_PERMISSIONS_CACHE, key = "#roleId + ':ids'")
    public Set<Long> getPermissionIdsByRoleId(Long roleId) {
        if (roleId == null) {
            return Collections.emptySet();
        }

        LambdaQueryWrapper<SysRolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRolePermission::getRoleId, roleId);
        // 注意：由于使用了物理删除，不需要过滤deleted字段

        List<SysRolePermission> rolePermissions = super.list(wrapper);
        if (CollectionUtils.isEmpty(rolePermissions)) {
            return Collections.emptySet();
        }

        return rolePermissions.stream()
                .map(SysRolePermission::getPermissionId)
                .collect(Collectors.toSet());
    }

    @Override
    @Cacheable(value = ROLE_PERMISSIONS_CACHE, key = "#roleId + ':codes'")
    public Set<String> getPermissionCodesByRoleId(Long roleId) {
        if (roleId == null) {
            return Collections.emptySet();
        }

        Set<Long> permissionIds = getPermissionIdsByRoleId(roleId);
        if (CollectionUtils.isEmpty(permissionIds)) {
            return Collections.emptySet();
        }

        // 查询权限详情
        LambdaQueryWrapper<SysPermission> permissionWrapper = new LambdaQueryWrapper<>();
        permissionWrapper.in(SysPermission::getId, permissionIds)
                       .eq(SysPermission::getDeleted, false)
                       .eq(SysPermission::getStatus, 1);

        List<SysPermission> permissions = permissionMapper.selectList(permissionWrapper);
        return permissions.stream()
                .map(SysPermission::getCode)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = {ROLE_PERMISSIONS_CACHE, PERMISSION_ROLES_CACHE}, allEntries = true)
    public void assignPermissionsToRole(Long roleId, List<Long> permissionIds) {
        if (roleId == null) {
            throw new BusinessException("角色ID不能为空");
        }
        if (CollectionUtils.isEmpty(permissionIds)) {
            log.warn("权限ID列表为空，跳过分配操作，角色ID: {}", roleId);
            return;
        }

        // 验证权限是否存在
        List<Long> validPermissionIds = validatePermissions(permissionIds);
        if (CollectionUtils.isEmpty(validPermissionIds)) {
            throw new BusinessException("没有有效的权限ID");
        }

        // 查询现有权限关联
        Set<Long> existingPermissionIds = getPermissionIdsByRoleId(roleId);

        // 计算需要新增的权限
        List<Long> newPermissionIds = validPermissionIds.stream()
                .filter(permissionId -> !existingPermissionIds.contains(permissionId))
                .collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(newPermissionIds)) {
            // 批量插入新的权限关联
            List<SysRolePermission> rolePermissions = newPermissionIds.stream()
                    .map(permissionId -> {
                        SysRolePermission rolePermission = new SysRolePermission();
                        rolePermission.setRoleId(roleId);
                        rolePermission.setPermissionId(permissionId);
                        return rolePermission;
                    })
                    .collect(Collectors.toList());

            super.saveBatch(rolePermissions);
            log.info("角色权限分配成功，角色ID: {}, 新增权限数量: {}", roleId, newPermissionIds.size());
        } else {
            log.info("所有权限已存在，无需重复分配，角色ID: {}", roleId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = {ROLE_PERMISSIONS_CACHE, PERMISSION_ROLES_CACHE}, allEntries = true)
    public void removePermissionsFromRole(Long roleId, List<Long> permissionIds) {
        if (roleId == null) {
            throw new BusinessException("角色ID不能为空");
        }
        if (CollectionUtils.isEmpty(permissionIds)) {
            return;
        }

        // 使用物理删除方式，直接在Mapper中完成
        int deletedCount = baseMapper.deleteByRoleIdAndPermissionIdsPhysically(roleId, permissionIds);
        if (deletedCount > 0) {
            log.info("角色权限移除成功，角色ID: {}, 移除权限数量: {}, 实际删除记录数: {}", roleId, permissionIds.size(), deletedCount);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = {ROLE_PERMISSIONS_CACHE, PERMISSION_ROLES_CACHE}, allEntries = true)
    public void clearRolePermissions(Long roleId) {
        if (roleId == null) {
            throw new BusinessException("角色ID不能为空");
        }

        // 使用物理删除方式，直接在Mapper中完成
        int deletedCount = baseMapper.deleteByRoleIdPhysically(roleId);
        if (deletedCount > 0) {
            log.info("角色权限清空成功，角色ID: {}, 删除记录数: {}", roleId, deletedCount);
        }
    }

    @Override
    public boolean hasPermission(Long roleId, Long permissionId) {
        if (roleId == null || permissionId == null) {
            return false;
        }

        Set<Long> permissionIds = getPermissionIdsByRoleId(roleId);
        return permissionIds.contains(permissionId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = {ROLE_PERMISSIONS_CACHE, PERMISSION_ROLES_CACHE}, allEntries = true)
    public void setRolePermissions(Long roleId, List<Long> permissionIds) {
        if (roleId == null) {
            throw new BusinessException("角色ID不能为空");
        }

        // 先清空现有权限
        clearRolePermissions(roleId);

        // 如果权限列表不为空，则添加新权限
        if (!CollectionUtils.isEmpty(permissionIds)) {
            assignPermissionsToRole(roleId, permissionIds);
        }

        log.info("角色权限重置成功，角色ID: {}, 权限数量: {}", roleId, 
                 permissionIds != null ? permissionIds.size() : 0);
    }

    @Override
    @Cacheable(value = PERMISSION_ROLES_CACHE, key = "#permissionId")
    public Set<Long> getRoleIdsByPermissionId(Long permissionId) {
        if (permissionId == null) {
            return Collections.emptySet();
        }

        LambdaQueryWrapper<SysRolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRolePermission::getPermissionId, permissionId);
        // 注意：由于使用了物理删除，不需要过滤deleted字段

        List<SysRolePermission> rolePermissions = super.list(wrapper);
        if (CollectionUtils.isEmpty(rolePermissions)) {
            return Collections.emptySet();
        }

        return rolePermissions.stream()
                .map(SysRolePermission::getRoleId)
                .collect(Collectors.toSet());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = {ROLE_PERMISSIONS_CACHE, PERMISSION_ROLES_CACHE}, allEntries = true)
    public void removePermissionFromAllRoles(Long permissionId) {
        if (permissionId == null) {
            throw new BusinessException("权限ID不能为空");
        }

        // 使用物理删除方式，直接在Mapper中完成
        int deletedCount = baseMapper.deleteByPermissionIdPhysically(permissionId);
        if (deletedCount > 0) {
            log.info("权限关联清理成功，权限ID: {}, 删除记录数: {}", permissionId, deletedCount);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = {ROLE_PERMISSIONS_CACHE, PERMISSION_ROLES_CACHE}, allEntries = true)
    public void removeRoleFromAllPermissions(Long roleId) {
        if (roleId == null) {
            throw new BusinessException("角色ID不能为空");
        }

        // 使用物理删除方式，直接在Mapper中完成
        int deletedCount = baseMapper.deleteByRoleIdPhysically(roleId);
        if (deletedCount > 0) {
            log.info("角色关联清理成功，角色ID: {}, 删除记录数: {}", roleId, deletedCount);
        }
    }

    /**
     * 验证权限ID是否有效
     */
    private List<Long> validatePermissions(List<Long> permissionIds) {
        if (CollectionUtils.isEmpty(permissionIds)) {
            return Collections.emptyList();
        }

        LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SysPermission::getId, permissionIds)
               .eq(SysPermission::getDeleted, false)
               .eq(SysPermission::getStatus, 1);

        List<SysPermission> validPermissions = permissionMapper.selectList(wrapper);
        return validPermissions.stream()
                .map(SysPermission::getId)
                .collect(Collectors.toList());
    }
}